#!-*- encoding:utf8 -*-
from django.template import Template, Context, RequestContext
from django.shortcuts import render_to_response
from django.contrib.auth.models import User
from django.contrib.auth.decorators import user_passes_test, login_required
from django.http import Http404, HttpResponseRedirect, HttpResponse
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger

from osmp.monitor.models import Monitor,AlertReceive, Alert
from osmp.host.models import Host, Product, Host2Pro
from osmp.report.models import Report, ReportReceive
from osmp.users.models import UserProfile, Authority
import osmp.daemon.conf as c
from osmp import settings
from osmp.util import commom

from django.db.models import Q

import urlparse,urllib
import csv,sys
import MySQLdb
import datetime
import hashlib
import math

@login_required
def monitorlist(request):
    """
    列出所有监控，并且实现分页操作
    """
    auth_pids = request.session['auth_pids']
    print auth_pids
    tree = ""  
    tree = commom.creatree(-1, tree, '', '/monitor/monitorlist?id=',  auth_pids = auth_pids)

    try:
        if request.method == 'POST':
            query = request.POST.get('query', '')
            q = Q(mname__contains = query) | Q(url__contains = query) 
            lst = Monitor.objects.filter(q)
        else:

            id = request.GET.get('id','-1')
            page = int(request.GET.get("page",1))
            if id == '-1':
                id = request.user.id
                lst_all = Monitor.objects.filter(pid__in = auth_pids)
                (lst, page_lst) = commom.pagination(lst_all, page)

            else:
                lst = Monitor.objects.filter(hid = Host.objects.get(id = id))


        #available
        yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
        alert = Alert.objects.filter(timestamp__gt = yesterday, type = '1')
        downtimes = {}
        sec_of_day = 86400 #24 * 60 * 60
        for e in alert:
            k = str(e.mid.id)
            if downtimes.has_key(k):
                downtimes[k] += e.downtime
            else:
                downtimes[k] = e.downtime
        for l in lst:
            if l.status != '1':
                l.available = "异常"
                continue

            k = str(l.id)
            errortime = downtimes.get(k, 0)
            l.available = r"%.2f" % ((1 - float(errortime)/sec_of_day) * 100)
            l.available += r"%"
    except:
        raise
    
    plist = Product.objects.all()
    request.session['plist'] = plist
    return render_to_response("monitor.html",locals())


@login_required
def errorlist(request):
    """
    列出所有监控，并且实现分页操作
    """
    auth_pids = request.session['auth_pids']
    print auth_pids
    tree = ""  
    tree = commom.creatree(-1, tree, '', '/monitor/errorlist?id=',  auth_pids = auth_pids)

    try:
        id = request.GET.get('id','-1')
        page = int(request.GET.get("page",1))
        if id == '-1':
            id = request.user.id
            lst_all = Monitor.objects.filter(pid__in = auth_pids, status=0)
            (lst, page_lst) = commom.pagination(lst_all, page)

        else:
            lst = Monitor.objects.filter(hid = Host.objects.get(id = id), status = 0)


        #available
        for l in lst:
            l.available = "异常"
            continue

    except:
        raise
    
    plist = Product.objects.all()
    request.session['plist'] = plist
    return render_to_response("monitorerror.html",locals())



@login_required
def addmonitor(request):
    """
    添加监控，添加完成以后，通知后台daemon程序，同时发出邮件
    """
    errors = []
    messages = []
    #根据请求方式判断操作
    if request.method == 'POST':
        #数据验证
        if not request.POST.get('mname', ''):
            errors.append('请输入监控名称')
        print len(request.POST.get('mname'))
        if len(request.POST.get('mname', '')) > 50:
            errors.append('监控名称过长，已经过超过50个字节')
        if not request.POST.get('url', ''):
            errors.append('请输入URL')
        if not request.POST.get('tpl',''):
            errors.append('请输入模版')
        if not request.POST.get('freq',''):
            errors.append('请输入监控频率')
        if not request.POST.get('alert_count',''):
            errors.append('请输入几次警报')
        if not request.POST.get('product',''):
            errors.append('请选择要监控的产品')
        if not request.POST.get('host',''):
            errors.append('请输入对应的主机')
        if not request.POST.get('mode',''):
            errors.append('请选择报警方式')
        if not request.POST.get('user',''):
            errors.append('请选择要通知的用户')
        if errors:
            #验证未通过 - 返回错误提示信息
            list = request.session.get('list')
            list1 = request.session.get('list1')
            return render_to_response("addmonitor.html",locals())
        if not errors:
            #验证通过 - 进行数据持久化操作 首先插入数据主表
            mname = request.POST.get('mname')
            #自动生成tablename,减少选择
            tablename = "data_" + hashlib.md5(mname.encode('utf-8')).hexdigest()[:16]  
            hostid = request.POST.get('host', '')
            m = Monitor.objects.create(
                    mname = mname,
                    url = request.POST.get('url'),
                    tpl = request.POST.get('tpl'),
                    freq = request.POST.get('freq'),
                    alert_count = request.POST.get('alert_count'),
                    table = tablename,
                    #默认添加
                    open = 1,
                    status = 1,
                    pid = Product.objects.get(id = request.POST.get('product', '')),
                    hid = Host.objects.get(id = request.POST.get('host', '')),
                )
            id = m.id
            uid = request.POST.getlist('user')
            mode = request.POST.getlist('mode')

            #从表数据持久化
            for u in uid:
                code = ['0', '0', '0', '0']
                print mode
                for e in mode:
                    code[int(e)] = '1'
                print code
                rr = AlertReceive.objects.create(
                        mid = Monitor.objects.get(id = id),
                        uid = User.objects.get(id = u),
                        mode = ''.join(code),
                    )
               #创建相关报表
            r = Report.objects.create(
                rname =u"[报表] %s" % request.POST.get('mname', ''),
                source = tablename,
                mid = m,
                type =  '0')
                    
            # - 再存ReportReceive表
            user = request.POST.getlist('user')
            for u in uid:
                rr = ReportReceive.objects.create(
                    rid = r,
                    uid = User.objects.get(id = u),
                    freq = 1,
                )

            #通知daemon端
            url ="http://%s/start/%d" % (settings.DAEMON_URI, m.id)
            print url
            fd = urllib.urlopen(url)
            data = fd.read()
            fd.close()

            messages.append('addsuccess')

            #邮件通知
            mail = request.session['user'].mail
            content = "监控： " + mname.encode('utf-8') + " 已经添加成功，请知晓。" 
            commom.sendmail(mail,"[NOTICE] OSMP Add Monitor",content)

            return HttpResponseRedirect("/monitor/monitorlist/?id=%s" % hostid)
            #return render_to_response( "addmonitor.html",locals())
    else:
        #无操作进入时 - 数据初始化
        list = Product.objects.filter(id__in = request.session['auth_pids'])
        for l in list:
            l.pname = l.name
        list2 = Host2Pro.objects.filter(pid__in = request.session['auth_pids'])
        for l in list2:
            l.hname = l.hid.name
            l.id = l.hid.id
        id = request.GET.get('id', '-1')
        print id
        if id != '-1':
            try:
                curhost = Host2Pro.objects.get(hid = int(id))
            except:
                pass
        list1 = UserProfile.objects.all()
        request.session['list'] = list
        request.session['list1'] = list1
        return render_to_response( "addmonitor.html",locals())

@login_required
def modifymonprj(request, id):
    """
    修改监控，同时通知daemon端和邮件通知修改人
    """
    if id:
        #进行数据修改的数据初始化
        moninfo = Monitor.objects.get(id = id)
        list = Product.objects.filter(id__in = request.session['auth_pids'])
        for l in list:
            l.pname = l.name

        list2 = Host2Pro.objects.filter(pid__in = request.session['auth_pids'])
        for l in list2:
            l.hname = l.hid.name
            l.id = l.hid.id
        
        recv = AlertReceive.objects.filter(mid = id).values()
        recv_lst = []
        for e in recv:
            recv_lst.append(e['uid_id'])

        print recv_lst
        list1 = UserProfile.objects.all()
        for u in list1:
            if u.user.id in recv_lst:
                u.ch = 1
            else:
                u.ch = 0

        #放入SESSION中 方便后面使用
        request.session['moninfo'] = moninfo
        request.session['list'] = list
        request.session['list1'] = list1
        request.session['list2'] = list2
        return render_to_response( "modifymonitor.html", locals())
    else:
        return HttpResponse('no id!!')
    
@login_required
def updatemonprj(request):
    if request.method == 'POST':
        errors = []
        messages = []
        if not request.POST.get('mname', ''):
            errors.append('请输入监控名称')
        if not request.POST.get('url', ''):
            errors.append('请输入URL')
        if not request.POST.get('tpl',''):
            errors.append('请输入模版')
        if not request.POST.get('freq',''):
            errors.append('请输入监控频率')
        if not request.POST.get('alert_count',''):
            errors.append('请输入几次警报')
        if not request.POST.get('product',''):
            errors.append('请选择要监控的产品')
        if not request.POST.get('host',''):
            errors.append('请输入对应的主机')
        if not request.POST.get('mode',''):
            errors.append('请选择报警方式')
        if not request.POST.get('user',''):
            errors.append('请选择要通知的用户')
        if errors:
            moninfo = request.session.get('moninfo')
            list = request.session.get('list')
            list1 = request.session.get('list1')
            return render_to_response("modifyreport.html",{'errors': errors,'moninfo':moninfo,'list':list,'list1':list1})
        if not errors:
            #修改 首先清除从表数据 
            id = request.POST.get('id')
            mname = request.POST.get('mname')
            ar = AlertReceive.objects.filter(mid = id)
            ar.delete()
            print "delete %s"%(id)
            #修改主表monitor
            m = Monitor.objects.get(id = id)
            m.mname = request.POST.get('mname')
            m.url = request.POST.get('url')
            m.tpl = request.POST.get('tpl')
            m.freq = request.POST.get('freq')
            m.alert_count = request.POST.get('alert_count')
            m.pid = Product.objects.get(id = request.POST.get('product', ''))
            m.hid = Host.objects.get(id = request.POST.get('host', ''))
            m.save()
            #子表数据重新生成
            id = m.id
            uid = request.POST.getlist('user')
            mode = request.POST.getlist('mode')
            for u in uid:
                code = ['0', '0', '0', '0']
                for e in mode:
                    print "%s ---- %s ---- %s "%(id,u,e)
                    code[int(e)] = '1'

                rr = AlertReceive.objects.create(
                        mid = Monitor.objects.get(id = id),
                        uid = User.objects.get(id = u),
                        mode = ''.join(code),
                    )

                       
            #通知daemon端
            url ="http://%s/reload/%d" % (settings.DAEMON_URI, id)
            fd = urllib.urlopen(url)
            data = fd.read()
            fd.close()

            #邮件通知
            try:
                mail = request.session['user'].mail
                content = "监控： " + mname.encode('utf-8') + " 已经修改成功，请知晓。" 
                commom.sendmail(mail,"[NOTICE] OSMP Modify Monitor",content)
            except:
                pass

            return HttpResponseRedirect("/monitor/monitorview/%d" % id )
            #messages.append('modifysuccess')
            #return render_to_response( "monitor.html",{'messages': messages})

@login_required
def deltemonprj(request, id):
    """
    修改监控，通知通知daemon端和删除监控人
    """
    messages = []
    if id:
        p = Monitor.objects.get(id = id)
        host = p.hid.id
        p.delete()
        messages.append("监控删除成功")

        #通知daemon端
        url ="http://%s/stop/%d" % (settings.DAEMON_URI, int(id))
        fd = urllib.urlopen(url)
        data = fd.read()
        fd.close()

        #邮件通知
        try:
            mail = request.session['user'].mail
            content = "监控： " + p.mname.encode('utf-8') + " 已经删除成功，请知晓。" 
            commom.sendmail(mail,"[NOTICE] OSMP Delete Monitor",content)
        except:
            print "have not mail"

        return HttpResponseRedirect("/monitor/monitorlist/?id=%s" % host)
        #return HttpResponseRedirect('/monitor')

@login_required
def monitorview(request, id):
    """
    显示监控图表
    """
    auth_pids = request.session['auth_pids']
    tree = ""  
    tree = commom.creatree(-1, tree, '', '/monitor/monitorlist?id=', auth_pids = auth_pids)
    
    if id:
        if request.session.get('data') != "":
                #request.session.clear()
                request.session['data'] = ""

        monitor = Monitor.objects.get(id = id)
        recv = AlertReceive.objects.filter(mid = monitor)
        table = monitor.table
        if request.method == 'POST':
            startTime = request.POST.get('start','')
            endTime = request.POST.get('end','')
            sql = 'SELECT timestamp, value from %s where timestamp> "%s 00:00:00" and timestamp < "%s 23:59:59"' % (table, startTime, endTime )
        else:
            startDate = datetime.date.today() - datetime.timedelta(days=1)
            startTime = startDate.strftime("%Y-%m-%d")
            sql = 'SELECT timestamp, value from %s where timestamp> "%s"' % (table, startTime )
            
        db = settings.DB
        conn = MySQLdb.connect(user=db['user'], db=db['name'], passwd=db['passwd'], host=db['host'], port= db['port'])
        #cursor = settings.DBCONN.cursor()
        cursor = conn.cursor()
        print sql
        cursor.execute(sql)
        rows = []
        for row in cursor.fetchall():
            rows.append('%s;%s' %(row[0].strftime("%Y-%m-%d %H:%M:%S"), row[1]))
        cursor.close()

        request.session['data'] = '\n'.join(rows)
        #设置Session有效期为关闭浏览器失效
        request.session.set_expiry(0)
        conn.close()
        return render_to_response("monitorview.html", locals())

@login_required
def dbtocsv(request):
    """
    缓存监控数据
    """
    data = request.session.get('data')
    return HttpResponse(data)

@login_required
def monitorstatus(requset, id):

    """
    ajax处理监控开启和关闭
    """
    if id:
        action = requset.GET.get('do','')
        
        if action == "stop":
            open = 0 
        if action == "start":
            open = 1 
                
        #修改数据库中的状态 
        m = Monitor.objects.get(id = id) 
        m.open = open
        if action == 'start':
            m.status = 1
        m.save() 

        surl = "http://" + c.listen + "/" + action + "/" + id
        url = urllib.urlopen(surl)
        rs = url.read()
        url.close()
        print surl
        
        begin = rs.find(":") + 1
        end = rs.find("|")
        str = rs[begin:end]
        print "----------"
        if str.lower() == "true":
            print "ok!!!"
        if str.lower() == "false":
            print "no!!!"
    return HttpResponseRedirect("/monitor/monitorlist/?id=%s" % m.hid.id)

#CSV的导出
import time
def export(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response.write('\xEF\xBB\xBF')
    tim = str(long(time.time()*1000))
    s = 'attachment; filename=Monitor-%s.csv'%tim
    response['Content-Disposition'] = s
    lst = request.session.get('lst')
    print lst
    writer = csv.writer(response)
    
    writer.writerow(['ID', u'监控名称'.encode('gbk'), 'URL', u'监控类型'.encode('gbk'), u'监控频率'.encode('gbk'), u'可用率'.encode('gbk')])
#    writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
    for l in lst:
        mname = l.mname.encode('gbk')
        writer.writerow([l.id,mname,l.url,l.tpl,l.freq,l.available])
    
    user = request.user.username
    now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    writer.writerow([u"用户：".encode('gbk'),user,u"操作时间：".encode('gbk'),now])
    return response
